home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_08_04
/
8n04117a
< prev
next >
Wrap
Text File
|
1990-03-18
|
3KB
|
92 lines
***************
** Listing 3 **
***************
/*
fork_execute() -- Execute the fork queue
This task executes all elements on the fork queue. While
the queue is executing, other elements can be place onto
the queue.
The queue operates by setting up a special TSS to be a
duplicate of the queued driver's TSS, except for the current
CS:IP and the stack. This allows all forked routines to
execute using the exact same environment it would have if
the task (or driver) had called the routine directly.
Actually, one enviromental difference may occur. All
routines executing on the fork will be run with
interrupts enabled.
In addition, the forked routine will be called in such a
manner that all it needs to do is issue a return to exit
the routine. The queue will handle the rest. Any return
value issued by the forked routine will be ignored. */
void fork_execute()
{
DWORD fork_addr;
OFFSET fork_sp;
SELECTOR fork_ss;
FORK_PARAM *owner;
unsigned char current_name[NAME_SIZE + 1];
current_name[NAME_SIZE] = '\0';
/* Initialize some constants, such as the base stack, and
the queue startup routine to use. */
fork_ss = fdummy_tcb.ss;
fork_sp = fdummy_tcb.sp;
fork_addr.whole = (unsigned long) fork_start;
/* Loop to continue task at each invokation */
while (1)
{
/* Tell the world that we are running the queue */
fork_in_process = 1;
/* As long as we have something to do.... */
while (fork_queue)
{
/* Get the next element */
owner = fork_queue;
fork_queue = fork_queue -> link;
/* Set up the information for fork_start() */
current_routine = owner -> routine;
current_param = owner -> param1;
/* Set up the TSS to give the target routine access
to the owning task's LDT. Also, set up for
interrupts enabled. */
movemem(owner -> tcb, &fdummy_tcb, 44);
fdummy_tcb.cs = fork_addr.high;
fdummy_tcb.ip = fork_addr.low;
fdummy_tcb.ss = fork_ss;
fdummy_tcb.sp = fork_sp;
fdummy_tcb.flag_word |= F_IE;
/* Execute task (Task switch) */
fdummy_task();
/* One less fork fork entry for this driver. */
((DSS *) owner -> tcb) -> current_fork_count--;
/* Place used entry back on free list */
owner -> link = fork_free;
fork_free = owner;
fork_count--;
}
/* Clear fork flag and reschedule */
fork_in_process = 0;
resume_cl(scheduler_task);
}
}